`timescale 1ns/1ns
`default_nettype none

/* NOTE:
*  - LED输出模块
*/

module pixel_display_top
    #(
    parameter   DW      = 6,
    parameter   DP      = 6
    )
    (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_sdram_clk, // 150M
    input  wire         I_rst_n,
    // frame
    input  wire         I_fake_frame_start,
    input  wire         I_frame_sync,
    // ext setting
    input  wire         I_ext_lock_output,
    input  wire         I_ext_black_screen,
    // config
    input  wire         I_cfg_output_enable, // 输出使能
    input  wire [2:0]   I_cfg_scan_mode,
    input  wire [7:0]   I_cfg_clock_low,     // 时钟低电平时钟数
    input  wire [7:0]   I_cfg_clock_cycle,   // 时钟整周期时钟数
    input  wire [7:0]   I_cfg_clock_phase,   // 时钟相位
    input  wire [7:0]   I_cfg_clock_phase_2, // 时钟相位2
    input  wire         I_cfg_245_version,   // 245芯片版本
    input  wire [5:0]   I_cfg_scan_max,      // 最大扫描id
    input  wire [5:0]   I_cfg_port_max,      // 最大端口id
    input  wire [7:0]   I_cfg_line_pos,      // 换行位置
    input  wire [5:0]   I_cfg_color_sel,     // RGB选择
    input  wire [31:0]  I_cfg_out_mask,      // 输出mask
    input  wire [15:0]  I_cfg_decode_param0, // 译码参数0
    input  wire [15:0]  I_cfg_decode_param1, // 译码参数1
    input  wire [15:0]  I_cfg_decode_param2, // 译码参数2
    input  wire [15:0]  I_cfg_deghost_ctrl_dly, // 消影信号延迟
    input  wire [15:0]  I_cfg_deghost_ctrl_len, // 消影信号长度
    input  wire [15:0]  I_cfg_rck_len,       // rck长度
    input  wire [7:0]   I_cfg_rck_num,       // rck个数
    input  wire [3:0]   I_cfg_decode_type,   // 译码方式
    input  wire [7:0]   I_cfg_chip_type,     // 芯片类型
    input  wire [1:0]   I_cfg_box_dir,       // 箱体方向
    input  wire [1:0]   I_cfg_block_max,     // 列模式下最大分区id
    input  wire [5:0]   I_cfg_col_port,      // 列模式下每个多开区域使用的数据组数
    input  wire         I_cfg_fps_sync_en,   // 帧率同步使能
    input  wire [7:0]   I_cfg_gclk_cycle,    // 灰度时钟分频数
    input  wire [7:0]   I_cfg_min_gclk_cycle,// 灰度时钟分频数
    input  wire [19:0]  I_cfg_gclk_total,    // 一帧时间内的gclk数-1
    input  wire [20:0]  I_cfg_frame_blank,   // 空白周期数
    input  wire [3:0]   I_cfg_hub_brd_type,  // G602使用的Hub板类型
    input  wire [511:0] I_cfg_pwm_setting,   // pwm芯片设置
    input  wire [15:0]  I_cfg_chain_cycle,
    input  wire [15:0]  I_cfg_min_chain,
    input  wire [11:0]  I_cfg_chain_num,
    
        // display buf
    output wire           O_ram_rden,
    output wire  [12:0]   O_ram_raddr,
    input  wire  [15:0]   I_ram_rdata,
    
    // scan map
    output wire         O_scan_map_rden,
    output wire [5:0]   O_scan_map_addr,
    input  wire [5:0]   I_scan_map_q,
    // port map
    output wire         O_port_map_rden,
    output wire [7:0]   O_port_map_addr,
    input  wire [5:0]   I_port_map_q,
    // column addr table
    output wire         O_col_addr_rclk,
    output wire         O_col_addr_req,
    output wire [8:0]   O_col_addr_index,
    input  wire [8:0]   I_col_addr_data,

    // pwm info
    output wire         O_pwm_info_rden,
    output wire [7:0]   O_pwm_info_addr,
    input  wire [31:0]  I_pwm_info_q,

    // frame id
    output wire         O_frame_req,
    input  wire [1:0]   I_frame_id,
    output wire [21:0]  O_display_sync_cycle,
    output wire [21:0]  O_display_display_cycle,
    // sdram mux
    input  wire         I_sdram_ready,
    output wire         O_read_sdram_req,
    input  wire         I_read_sdram_ack,
    input  wire         I_read_sdram_irq,
    output wire         O_read_sdram_cs_n,
    output wire         O_read_sdram_ras_n,
    output wire         O_read_sdram_cas_n,
    output wire         O_read_sdram_we_n,
    output wire [1:0]   O_read_sdram_ba,
    output wire [10:0]  O_read_sdram_addr,
    output wire [31:0]  O_read_sdram_dq_out,
    input  wire [31:0]  I_read_sdram_dq_in,
    output wire         O_read_sdram_dq_oe,
    output wire [3:0]   O_read_sdram_dqm,
    // led signal
    output wire         O_oe_out,
    output wire         O_load_out,
    output wire [4:0]   O_scan_out,
    output wire         O_clock_out,
    output wire [DP-1:0] O_data_out,
    output wire         O_deghost_ctrl,
    input  wire         I_time_1ms_sync,
    output wire [15:0]  tout
);

//------------------------Parameter----------------------
// chip type
localparam
    CHIP_ICN2053  = 1,
    CHIP_ICND2055 = 50,
    CHIP_ICND2065 = 51,
    CHIP_ICND2163 = 52,
    CHIP_ICND2153 = 56,
    CHIP_SM16159S = 10,
    CHIP_SM16169S = 36,
    CHIP_SUM2033  = 20,// sum2036 sum2037 sum2130 sum2130T sum2131 
    CHIP_SUM2035  = 21,
    CHIP_SUM2028  = 22,
    CHIP_MBI5153  = 30,
    CHIP_MBI5155  = 31,
    CHIP_MBI5051  = 32,
    CHIP_MBI5151  = 33,
    CHIP_MBI5252  = 34,
    CHIP_MBI5353  = 35,
    CHIP_MBI5353B = 61,
    CHIP_SM16259S = 11,
    CHIP_MY9748   = 60,
    CHIP_HX8055   = 70,
    CHIP_FM6353   = 72,
    CHIP_FM6356   = 73,
    CHIP_MBI5043  = 71;

//------------------------Local signal-------------------
// read request
wire        read_req;         // 读请求
wire        read_busy;        // 读忙碌
wire [1:0]  read_buf_sel;     // 读取SDRAM分块地址
wire [5:0]  read_scan_id;     // 读取的scan id
wire [5:0]  read_port_max;    // 读取的最大port id
wire [5:0]  read_pin_id;      // 读取的芯片管脚id，0 - 63
wire [4:0]  read_chip_max;    // 读取的最大芯片id
wire [4:0]  read_chip_id;     // 读取的芯片id
wire        read_buf_index;   // 

// display buf
wire        ram_wclk;
wire        ram_rclk;
wire        ram_rden;
wire [DW-1:0] ram_rdata;

wire [31:0] ram_wdata;
wire [11:0] ram_raddr;
wire [8:0]  ram_waddr;
wire [8:0]  read_ram_addr;    // 存放到RAM的起始地址
wire [7:0]  ram_wren;


// mbi5353
reg         chip_enable_5353b;
reg         chip_enable;
wire        chip_frame_req;
wire        chip_display_ready;
wire        chip_display_end;
wire        chip_read_req;
wire [1:0]  chip_read_buf_sel;
wire [5:0]  chip_read_scan_id;
wire [5:0]  chip_read_port_max;
wire [5:0]  chip_read_pin_id;
wire [5:0]  chip_read_chip_id;
wire [5:0]  chip_read_pin_max;
wire [5:0]  chip_read_chip_max;
wire [8:0]  chip_read_ram_addr;


wire        chip_read_buf_index;

wire        chip_ram_rden;
wire [11:0] chip_ram_raddr;
wire        chip_scan_prep;
wire        chip_scan_commit;
wire [5:0]  chip_scan_num;
wire        chip_oe_out;
wire        chip_load_out;
wire        chip_clock_out;
wire [DW-1:0] chip_data_out;


// scan decoder
wire        scan_prep;
wire        scan_commit;
wire [5:0]  scan_num;
wire [4:0]  scan_out;
wire        deghost_ctrl;

// led signal
reg         oe_out0;
reg         load_out0;
reg [4:0]   scan_out0;
reg         clock_out0;
reg [DW-1:0] data_out0;
reg         deghost_ctrl0;

// fps sync         
wire        display_reset;
wire        display_ready;
wire        display_end;
wire [7:0]  display_gclk_low;
wire [7:0]  display_gclk_cycle;
wire [19:0] display_gclk_extra;

wire        display_chain_end;
wire        display_param_en;
wire [15:0] display_chain_cycle;
wire [15:0] display_extra_cycle;

reg         fake_frame_en;

//------------------------Instantiation------------------
// cxy_pixel_reader_MBI5353
pixel_reader_31_5_5353b
    #(
    .DW             (DW             )
    )
    reader (/*{{{*/
    .I_sclk           ( I_sclk ),
    .I_rst_n          ( I_rst_n ),
    
    // .set_clk          ( set_clk ),
    // .set_d_ok         ( set_d_ok),
    // .set_addr         ( set_addr),
    // .set_data         ( set_data),
    
    .I_read_req       ( read_req ),

    .O_read_busy      ( read_busy ),
    .I_read_scan_id   ( read_scan_id ),
    .I_read_port_max  ( read_port_max ),
    .I_read_pin_id    ( read_pin_id ),
    .I_read_chip_max  ( read_chip_max ),
    .I_read_buf_index ( read_buf_index ),
    
    .O_ram_wclk       ( ram_wclk ),
    .O_ram_wren       ( ram_wren ),
    .O_ram_addr       ( ram_waddr ),
    .O_ram_data       ( ram_wdata ),
    
    .O_back_ram_en    ( O_ram_rden ),   
    .O_back_ram_addr  ( O_ram_raddr ),
    .I_back_data      ( I_ram_rdata )
);

// cxy_pixel_display_buf_MBI5353
cxy_pixel_display_buf_MBI5353 /*{{{*/
    #(
    .DW             (DW             )
    )
  db (
    .I_wclk         (ram_wclk       ),
    .I_wren         (ram_wren       ),
    .I_waddr        (ram_waddr      ),
    .I_wdata        (ram_wdata      ),

    .I_rclk         (ram_rclk       ),
    .I_rden         (ram_rden       ),
    .I_raddr        (ram_raddr      ),
    .O_rdata        (ram_rdata      )
);/*}}}*/


// pixel_display_mbi5353
pixel_display_mbi5353 /*{{{*/
    #(
    .DW                   (DW       )
    )
  mbi5353 (
    .I_sclk               ( I_sclk ),
    .I_rst_n              ( I_rst_n ),
    .I_enable             ( chip_enable ),
    .I_enable_5353b       ( chip_enable_5353b   ),
    .I_ext_lock_output    ( I_ext_lock_output ),
    .I_ext_black_screen   ( I_ext_black_screen ),
    .I_cfg_clock_low      ( I_cfg_clock_low ),
    .I_cfg_clock_cycle    ( I_cfg_clock_cycle ),
    .I_cfg_clock_phase    ( I_cfg_clock_phase ),
    .I_cfg_scan_max       ( I_cfg_scan_max ),
    .I_cfg_port_max       ( I_cfg_port_max ),
    .I_cfg_line_pos       ( I_cfg_line_pos ),
    .I_cfg_out_mask       ( I_cfg_out_mask ),
    .I_cfg_pwm_setting    ( I_cfg_pwm_setting ),
    .O_frame_req          ( chip_frame_req ),
    .I_frame_id           ( I_frame_id ),
    .I_display_reset      ( display_reset ),
    .O_display_ready      ( chip_display_ready ),
    .O_display_end        ( chip_display_end ),
    .I_display_gclk_low   ( display_gclk_low ),
    .I_display_gclk_cycle ( display_gclk_cycle ),
    .I_display_gclk_extra ( display_gclk_extra ),
    .O_read_req           ( chip_read_req ),
    .I_read_busy          ( read_busy ),
    .O_read_buf_sel       ( chip_read_buf_sel ),
    .O_read_scan_id       ( chip_read_scan_id ),
    .O_read_port_max      ( chip_read_port_max ),
    .O_read_pin_id        ( chip_read_pin_id ),
    .O_read_chip_max      ( chip_read_chip_max ),
    .O_read_ram_addr      ( chip_read_ram_addr ),
    
    .O_read_buf_index     ( chip_read_buf_index),
    
    .O_ram_rden           ( chip_ram_rden ),
    .O_ram_raddr          ( chip_ram_raddr ),
    .I_ram_rdata          ( ram_rdata ),
    .O_scan_prep          ( chip_scan_prep ),
    .O_scan_commit        ( chip_scan_commit ),
    .O_scan_num           ( chip_scan_num ),
    .O_oe_out             ( chip_oe_out ),
    .O_load_out           ( chip_load_out ),
    .O_clock_out          ( chip_clock_out ),
    .O_data_out           ( chip_data_out ),
    .I_time_1ms_sync      ( I_time_1ms_sync )
);/*}}}*/

// cxy_scan_decoder
cxy_scan_decoder sd (/*{{{*/
    .I_sclk              ( I_sclk ),
    .I_rst_n             ( I_rst_n ),
    .I_cfg_scan_max      ( I_cfg_scan_max ),
    .I_cfg_decode_type   ( I_cfg_decode_type ),
    .I_cfg_decode_param0 ( I_cfg_decode_param0 ),
    .I_cfg_decode_param1 ( I_cfg_decode_param1 ),
    .I_cfg_deghost_ctrl_dly (I_cfg_deghost_ctrl_dly ),
    .I_cfg_deghost_ctrl_len (I_cfg_deghost_ctrl_len ),
    .I_cfg_decode_param2 ( I_cfg_decode_param2 ),
    .I_cfg_rck_len       ( I_cfg_rck_len ),
    .I_cfg_rck_num       ( I_cfg_rck_num ),
    .I_scan_prep         ( scan_prep ),
    .I_scan_num          ( scan_num ),
    .I_scan_commit       ( scan_commit ),
    .I_display_end       ( display_end           ),
    .O_deghost_ctrl      ( deghost_ctrl ),
    .O_scan_out          ( scan_out )
);/*}}}*/


`ifdef SUM2028
// cxy_fps_sync_sum2028
cxy_fps_sync_sum2028 #(/*{{{*/
    .MAX_PHASE_ERROR        (2000                   )
    )
  sync(
    .I_sclk                 (I_sclk                 ),
    .I_rst_n                (I_rst_n                ),
    .I_cfg_output_enable    (I_cfg_output_enable    ),
    .I_cfg_fps_sync_en      (I_cfg_fps_sync_en      ),

    .I_cfg_chain_cycle      (I_cfg_chain_cycle      ),
    .I_cfg_min_chain        (I_cfg_min_chain        ),
    .I_cfg_chain_num        (I_cfg_chain_num        ),

  //.I_frame_sync           (I_frame_sync           ),
    .I_frame_sync           (I_frame_sync | I_fake_frame_start),

    .O_display_reset        (display_reset          ),
    .I_display_ready        (display_ready          ),
    .I_display_end          (display_end            ),
    .I_display_chain_end    (display_chain_end      ),
    .O_display_param_en     (display_param_en       ),
    .O_display_chain_cycle  (display_chain_cycle    ),
    .O_display_extra_cycle  (display_extra_cycle    )
    );/*}}}*/
`else
// cxy_fps_sync
cxy_fps_sync #(/*{{{*/
    .MAX_PHASE_ERROR        (20000                  )
) sync (
    .I_sclk                 (I_sclk                 ),
    .I_rst_n                (I_rst_n                ),
    .I_cfg_output_enable    (I_cfg_output_enable    ),
    .I_cfg_fps_sync_en      (I_cfg_fps_sync_en      ),
    .I_cfg_gclk_cycle       (I_cfg_gclk_cycle       ),
    .I_cfg_min_gclk_cycle   (I_cfg_min_gclk_cycle   ),
    .I_cfg_gclk_total       (I_cfg_gclk_total       ),
    .I_cfg_frame_blank      (I_cfg_frame_blank      ),

  //.I_frame_sync           (I_frame_sync           ),
    .I_frame_sync           (I_frame_sync | I_fake_frame_start ),

    .O_display_reset        (display_reset          ),
    .I_display_ready        (display_ready          ),
    .I_display_end          (display_end            ),
    .O_display_gclk_low     (display_gclk_low       ),
    .O_display_gclk_cycle   (display_gclk_cycle     ),
    .O_display_gclk_extra   (display_gclk_extra     )
    // .tout                   ( )
);/*}}}*/
`endif

//------------------------Body---------------------------
//{{{+++++++++++++++++++++read request+++++++++++++++++++
// NOTE: 不同PWM芯片控制模块信号进行或运算
assign read_req      = chip_read_req;

assign read_buf_sel  = chip_read_buf_sel;

assign read_scan_id  = chip_read_scan_id;

assign read_port_max = chip_read_port_max;

assign read_pin_id   = chip_read_pin_id;

assign read_chip_max = chip_read_chip_max;

assign read_ram_addr = chip_read_ram_addr;

assign read_chip_id  = chip_read_chip_id;    

assign read_buf_index = chip_read_buf_index;                      
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++display buf++++++++++++++++++++
// NOTE: 不同PWM芯片控制模块信号进行或运算
assign ram_rclk  = I_sclk;
assign ram_rden  = chip_ram_rden;

assign ram_raddr = chip_ram_raddr;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++chip control+++++++++++++++++++
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n) begin
        chip_enable <= 1'b0;
        chip_enable_5353b <= 1'b0;

    end
    else begin
        chip_enable <= I_cfg_output_enable && I_sdram_ready && (I_cfg_chip_type == CHIP_MBI5353 || I_cfg_chip_type == CHIP_MBI5353B);
        chip_enable_5353b <= I_cfg_output_enable && I_sdram_ready && (I_cfg_chip_type == CHIP_MBI5353B);
    end
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++scan decoder+++++++++++++++++++
// NOTE: 不同PWM芯片控制模块信号进行或运算
assign scan_prep   =  chip_scan_prep ;

assign scan_commit = chip_scan_commit ;

assign scan_num    =  chip_scan_num ;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++frame id+++++++++++++++++++++++
// NOTE: 不同PWM芯片控制模块信号进行或运算
assign O_frame_req = fake_frame_en ? 1'b0 : chip_frame_req;

//fake_frame_en
always@(posedge I_sclk or negedge I_rst_n)
    if(!I_rst_n)
        fake_frame_en <= 'b0;
    else if(I_frame_sync)
        fake_frame_en <= 'b0;
    else if(I_fake_frame_start)
        fake_frame_en <= 1'b1;

//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++led signal+++++++++++++++++++++
assign O_oe_out    = oe_out0;
assign O_load_out  = load_out0;
assign O_scan_out  = scan_out0;
assign O_clock_out = clock_out0;
assign O_data_out  = data_out0;
assign O_deghost_ctrl = deghost_ctrl0;
// scan_outx
always@(posedge I_sclk)
    begin
        scan_out0  <= {1'b1,scan_out[3:0]};

        deghost_ctrl0  <= deghost_ctrl;

        oe_out0    <= chip_oe_out;

        load_out0  <= chip_load_out;

        clock_out0 <= chip_clock_out;

        data_out0  <= chip_data_out;
    end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++fps sync+++++++++++++++++++++++
// NOTE: 不同PWM芯片控制模块信号进行或运算
assign display_ready = chip_display_ready;

assign display_end   =  chip_display_end;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
